package com.autonavi.yunda.yunji.common.web;

import org.apache.commons.io.IOUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * @author cizhong.wcs
 * @date 2022/2/16 2:57 下午
 */
public class ReReadableRequestWrapper extends HttpServletRequestWrapper {
    //todo 解决 getParameterValues无法正常获取x-www-form-urlencoded数据问题
//    protected boolean parametersParsed;
//    private final Parameters parameters = new Parameters();
    private final byte[] body;

    public ReReadableRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = IOUtils.toByteArray(request.getInputStream());

    }


    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(this.getInputStream(), StandardCharsets.UTF_8));
    }

    @Override
    public ServletInputStream getInputStream() {
        return new ReReadableServletInputStream(body);
    }

//    @Override
//    public String[] getParameterValues(String key) {
//        return null;
//    }

//    protected void parseParameters() {
//    }

    private static class ReReadableServletInputStream extends ServletInputStream {

        private final ByteArrayInputStream in;

        public ReReadableServletInputStream(byte[] bytes) {
            this.in = new ByteArrayInputStream(bytes);
        }

        @Override
        public boolean isFinished() {
            return in.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener readListener) {
            throw new RuntimeException("Not implemented");
        }

        @Override
        public int read() throws IOException {
            return this.in.read();
        }
    }
}
